﻿using System;
using System.Linq;
using System.Web.Mvc;
using Project.DAL.Repository;
using MvcContrib.Pagination;
using Project.Domain.Entities;

namespace Project.WebUI.Controllers
{
    public class SportController : Controller
    {      
        #region "private"        
        private readonly IMatchesRepository _matchesRepository;
        private readonly ILeagueRepository _leagueRepository;
        private readonly ICommonRepository _commonRepository;
        private readonly ISoccerTeamRepository _soccerTeamRepository;
        private readonly IBetRepository _betRepository;
        private readonly IUserRepository _userRepository;        
        private readonly IBetDetailRepository _betDetailRepository;

        public SportController(IMatchesRepository matchesRepository,
            ILeagueRepository leagueRepository,
            ICommonRepository commonRepository,
            ISoccerTeamRepository soccerTeamRepository,
            IBetRepository betRepository,
            IUserRepository userRepository,            
            IBetDetailRepository betDetailRepository)
        {
            _matchesRepository = matchesRepository;
            _leagueRepository = leagueRepository;
            _commonRepository = commonRepository;
            _soccerTeamRepository = soccerTeamRepository;
            _betRepository = betRepository;
            _userRepository = userRepository;            
            _betDetailRepository = betDetailRepository;
        }

        #endregion        

        //step1:
        public ActionResult Ajaxsoccer()
        {
            var listLeague =
                _leagueRepository.GetMany(l => l.IsPlay &&
                                               l.Matches.Count(m => m.IsPlay == 0 & m.Status) > 0);
            return PartialView("_soccerZone", listLeague);
        }

        /// <summary>
        /// step2
        /// </summary>
        /// <param name="leagueid"></param>
        /// <returns></returns>
        #region "getAllMatchByLeagueId"
        public ActionResult GetAllMatchOfLeague(int leagueid)
        {
            var listmatch = _matchesRepository.GetMany(m => m.LeagueId.Equals(leagueid) & m.IsPlay == 0 & m.Status,
                                                       o => o.OrderBy(m => m.TimePlay), "HomeTeam,AwayTeam");
            ViewBag.leagueid = "listajaxallmatch" + leagueid;
            return PartialView("_getAllMatchOfLeague", listmatch);
        }
        #endregion

        /// <summary>
        /// Step3,4
        /// </summary>
        /// <param name="matchid"></param>
        /// <param name="matchId"> </param>
        /// <returns></returns>
        public ActionResult GetBetOfmatch(int matchId)
        {
            //list user create Bet By matchid( store in bets);
            ViewBag.Userbets = _betRepository.GetUserCreateBet(matchId);                
            ViewBag.MatchId = matchId;
            
            //list all bet of match
            var listbetOfMatch = _betRepository.GetMany(b => b.MatchId.Equals(matchId));
            return PartialView("_getBetOfMatch", listbetOfMatch);
        }

        /// <summary>
        /// step5,6,7
        /// </summary>
        /// <param name="betid"></param>
        /// <param name="userid"></param>
        /// <returns></returns>
        public ActionResult GetBetDetails(int betid, int userid)
        {
            var bet = _betRepository.GetById(betid);
            ViewBag.ScoreHome = bet.ScoreHomeBefore.ToString();
            ViewBag.ScoreAway = bet.ScoreAwayBefore.ToString();
            var listbet3Way = _betDetailRepository
                .GetMany(b => b.BetId == betid
                              && b.Bet.UserId == userid, null, "Bet");
            switch (bet.Type)
            {
                case 1:
                    {
                        return PartialView("_GetBetDetail3Way", listbet3Way);                        
                    }
                case 2:
                    {
                        return PartialView("_GetBetDetailHandicap", listbet3Way);
                    }
                default:
                    {
                        return PartialView("_GetBetDetailAsianHandicap", listbet3Way);
                    }
            }
        }
        /// <summary>
        ///step 8 //using 3way to Under-Over
        /// </summary>
        /// <param name="betid"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public ActionResult GetbetUnderOver(int betId, int userId)
        {
            var listBetUnderOver = _betDetailRepository
                .GetMany(b => b.BetId.Equals(betId)
                              && b.Bet.UserId.Equals(userId), null, "Bet");
            return PartialView("_getbetUnderOver", listBetUnderOver);
        }

        /// <summary>
        /// step9://using exact score
        /// </summary>
        /// <param name="matchid"></param>
        /// <param name="userid"></param>
        /// <returns></returns>
        public ActionResult GetbetExactScore(int matchid, int userid)
        {
            var listBetExactScore = _betDetailRepository
                .GetMany(b => b.Bet.MatchId.Equals(matchid)
                              && b.Bet.Type == 5
                              && b.Bet.UserId.Equals(userid), null, "Bet");
            var countExact = listBetExactScore.Count();
            ViewBag.countExact = countExact;
            return PartialView("_getbetExactScore", listBetExactScore);
        }
        //get giai dau co tran dau :status=true:
        #region GetAllLeague
        public ActionResult GetAllLeague()
        {
            var league = _leagueRepository.GetMany(l => l.IsPlay)
                .OrderBy(l => l.LeagueId);
            return PartialView("_allleague", league);
        }
        #endregion
        
        //khi dropdowlist league change lay doi chu nha.
        #region GetHometeam
        public ActionResult GetHometeam(int leagueId)
        {
            var listHomeTeam = _soccerTeamRepository.GetHomeTeamByLeagueId(leagueId, 1, 0);
            return PartialView("_hometeam", listHomeTeam);
        }
        #endregion
        
        //khi dropdowlist league change lay doi khach
        #region GetAwayteam
        public ActionResult GetAwayteam(int leagueId)
        {
            var listAwayTeam = _soccerTeamRepository.GetAwayTeamByLeagueId(leagueId, 1, 0);
            return PartialView("_awayteam", listAwayTeam);
        }
        #endregion
        
        //khi chon doi chu nha thi thay doi doi khach
        #region Getawaybyhome
        public ActionResult Getawaybyhome(int hometeamid, int leagueId)
        {
            var match = _matchesRepository
                .Get(m => m.HomeTeamId == hometeamid && m.Status && m.IsPlay == 0);
            if (match != null)
            {
                ViewBag.away = match.AwayTeamId;
            }
            var listAwayTeam = _soccerTeamRepository.GetAwayTeamByLeagueId(leagueId, 1, 0);
            return PartialView("_getawaybyhome", listAwayTeam);
        }
        #endregion
        
        //khi thay doi doi khach thi thay doi chu nha
        #region Gethomebyaway
        public ActionResult Gethomebyaway(int awayteamid, int leagueid)
        {
            var match = _matchesRepository
                .Get(m => m.AwayTeamId == awayteamid && m.Status && m.IsPlay == 0);
            if (match != null)
            {
                ViewBag.home = match.HomeTeamId;
            }
            var listHomeTeam = _soccerTeamRepository.GetHomeTeamByLeagueId(leagueid, 1, 0);
            return PartialView("_gethomebyaway", listHomeTeam);
        }
        #endregion        

        #region ChangeHtmlOdds
        public ActionResult ChangeHtmlOdds(int categoryid)
        {
            return PartialView("_htmlodds" + categoryid);
        }
        #endregion
       
        #region NewBet
        public ActionResult NewBet()
        {
            var culture = "";
            if (Session["Culture"] != null && Session["Culture"].ToString().Equals("vi-VN"))
            {
                culture = "vi-VN";
            }
            ViewBag.Notes = _commonRepository.GetMany(c => c.Type.Equals("notes_content"));
            var titleNotes = _commonRepository.Get(c => c.Type.Equals("notes_title"));
            ViewBag.TitleNotes = culture == "vi-VN" ? titleNotes.Content : titleNotes.ContentEn;
            return View();
        }

        [HttpPost]
        public ActionResult Newbet(Bet betModel, FormCollection fc)
        {
            var leagueid = Convert.ToInt32(fc["LeagueID"]);
            var homeTeamId = Convert.ToInt32(fc["HomeTeamID"]);
            var awayTeamId = Convert.ToInt32(fc["AwayTeamID"]);
            var categoryId = Convert.ToInt32(fc["CategoryID"]);
            var oddsmax = Convert.ToDecimal(fc["oddsmax"]);

            var match =
                _matchesRepository.Get(
                    m => m.HomeTeamId == homeTeamId
                         && m.AwayTeamId == awayTeamId
                         && m.LeagueId == leagueid
                         && m.Status
                         && m.IsPlay == 0);

            var user = _userRepository.Get(u => u.UserName.Equals(User.Identity.Name));

            if (user == null)
                return Content("4");

            if (match == null)
                return Content("4");

            if (user.Balance < oddsmax)
                return Content("0");

            var bet = new Bet
                          {
                              MatchId = match.MatchId,
                              UserId = user.UserId,
                              Type = categoryId,
                              Status = false,
                              MaxBet = oddsmax,
                              CreatedTime = DateTime.Now,
                              CurrentBet = oddsmax,
                          };

            switch (categoryId)
            {
                case 1:
                    {
                        try
                        {
                            var oddshome = Convert.ToDecimal(fc["oddshome"]);
                            var oddsdraw = Convert.ToDecimal(fc["oddsdraw"]);
                            var oddsaway = Convert.ToDecimal(fc["oddsaway"]);

                            user.Balance -= oddsmax;
                            _userRepository.SaveChanges();
                            _betRepository.Add(bet);
                            _betRepository.SaveChanges();

                            var betDetailHome = new BetDetail
                                                    {
                                                        OddsHome = oddshome,
                                                        CreatedTime = DateTime.Now,
                                                        Status = true,
                                                        Type = 1,
                                                        BetId = bet.BetId
                                                    };
                            _betDetailRepository.Add(betDetailHome);

                            var betDetailDraw = new BetDetail
                                                    {
                                                        BetId = bet.BetId,
                                                        OddsDraw = oddsdraw,
                                                        CreatedTime = DateTime.Now,
                                                        Status = false,
                                                        Type = 2
                                                    };
                            _betDetailRepository.Add(betDetailDraw);

                            var betDetailAway = new BetDetail
                                                    {
                                                        BetId = bet.BetId,
                                                        OddsAway = oddsaway,
                                                        CreatedTime = DateTime.Now,
                                                        Status = false,
                                                        Type = 3
                                                    };
                            _betDetailRepository.Add(betDetailAway);
                            _betDetailRepository.SaveChanges();
                            return Content("1");
                        }
                        catch (Exception e)
                        {
                            ModelState.AddModelError("",
                                                     "bet creation was unsuccessful,Please correct enter value and try again");
                            return Content("5");
                        }
                    }
                    //3wayhandicap            
                case 2:
                    {
                        try
                        {
                            var oddshome = Convert.ToDecimal(fc["oddshome"]);
                            var oddsdraw = Convert.ToDecimal(fc["oddsdraw"]);
                            var oddsaway = Convert.ToDecimal(fc["oddsaway"]);
                            var scorehome = Convert.ToDecimal(fc["scorehome"]);
                            var scoreaway = Convert.ToDecimal(fc["scoreaway"]);

                            user.Balance -= oddsmax;
                            _userRepository.SaveChanges();
                            bet.ScoreHomeBefore = scorehome;
                            bet.ScoreAwayBefore = scoreaway;
                            _betRepository.Add(bet);
                            _betRepository.SaveChanges();

                            var betDetailHome = new BetDetail
                                                    {
                                                        OddsHome = oddshome,
                                                        CreatedTime = DateTime.Now,
                                                        Status = false,
                                                        Type = 1,
                                                        BetId = bet.BetId
                                                    };
                            _betDetailRepository.Add(betDetailHome);

                            var betDetailDraw = new BetDetail
                                                    {
                                                        BetId = bet.BetId,
                                                        OddsDraw = oddsdraw,
                                                        CreatedTime = DateTime.Now,
                                                        Status = false,
                                                        Type = 2
                                                    };
                            _betDetailRepository.Add(betDetailDraw);

                            var betDetailAway = new BetDetail
                                                    {
                                                        BetId = bet.BetId,
                                                        OddsAway = oddsaway,
                                                        CreatedTime = DateTime.Now,
                                                        Status = false,
                                                        Type = 3
                                                    };
                            _betDetailRepository.Add(betDetailAway);
                            _betDetailRepository.SaveChanges();
                            return Content("1");
                        }
                        catch (Exception)
                        {
                            ModelState.AddModelError("",
                                                     "bet creation was unsuccessful,Please correct enter value and try again");
                            return Content("5");
                        }
                    }

                case 3:
                    {
                        try
                        {
                            var oddshome = Convert.ToDecimal(fc["oddshome"]);
                            var oddsaway = Convert.ToDecimal(fc["oddsaway"]);
                            var scorehome = Convert.ToDecimal(fc["scorehome"]);
                            var scoreaway = Convert.ToDecimal(fc["scoreaway"]);

                            user.Balance -= oddsmax;
                            _userRepository.SaveChanges();
                            bet.ScoreHomeBefore = scorehome;
                            bet.ScoreAwayBefore = scoreaway;
                            _betRepository.Add(bet);
                            _betRepository.SaveChanges();

                            var betDetailHome = new BetDetail
                                                    {
                                                        OddsHome = oddshome,
                                                        CreatedTime = DateTime.Now,
                                                        Status = false,
                                                        BetId = bet.BetId,
                                                        Type = 1
                                                    };
                            _betDetailRepository.Add(betDetailHome);
                            var betDetailAway = new BetDetail
                                                    {
                                                        BetId = bet.BetId,
                                                        OddsAway = oddsaway,
                                                        CreatedTime = DateTime.Now,
                                                        Status = false,
                                                        Type = 2
                                                    };
                            _betDetailRepository.Add(betDetailAway);
                            _betDetailRepository.SaveChanges();
                            return Content("1");
                        }
                        catch (Exception)
                        {
                            ModelState.AddModelError("",
                                                     "bet creation was unsuccessful,Please correct enter value and try again");
                            return Content("5");
                        }
                    }
                case 4:
                    {
                        try
                        {
                            var rate = Convert.ToDecimal(fc["rateunderover"]);
                            var oddsunder = Convert.ToDecimal(fc["oddsunder"]);
                            var oddsover = Convert.ToDecimal(fc["oddsover"]);

                            user.Balance -= oddsmax;
                            _userRepository.SaveChanges();
                            _betRepository.Add(bet);
                            _betRepository.SaveChanges();

                            var betdetailunder = new BetDetail
                                                     {
                                                         RateUnderOver = rate,
                                                         OddsUnder = oddsunder,
                                                         CreatedTime = DateTime.Now,
                                                         Type = 1,
                                                         BetId = bet.BetId,
                                                         Status = false
                                                     };
                            _betDetailRepository.Add(betdetailunder);
                            var betdetailover = new BetDetail
                                                    {
                                                        RateUnderOver = rate,
                                                        OddsOver = oddsover,
                                                        CreatedTime = DateTime.Now,
                                                        Type = 2,
                                                        BetId = bet.BetId
                                                    };
                            _betDetailRepository.Add(betdetailover);
                            _betDetailRepository.SaveChanges();
                            return Content("1");
                        }
                        catch (Exception)
                        {
                            ModelState.AddModelError("",
                                                     "bet creation was unsuccessful,Please correct enter value and try again");
                            return Content("5");
                        }
                    }
                case 5:
                    {
                        {
                            var scorehome = Convert.ToDecimal(fc["scorehome"]);
                            var scoreaway = Convert.ToDecimal(fc["scoreaway"]);
                            var oddsexact = Convert.ToDecimal(fc["oddsexact"]);

                            user.Balance -= oddsmax;
                            _userRepository.SaveChanges();
                            bet.ScoreHomeBefore = scorehome;
                            bet.ScoreAwayBefore = scoreaway;
                            _betRepository.Add(bet);
                            _betRepository.SaveChanges();
                            var betdetailexact = new BetDetail
                                                     {
                                                         CreatedTime = DateTime.Now,
                                                         OddsExactScore = oddsexact,
                                                         Type = 1,
                                                         BetId = bet.BetId,
                                                         Status = false
                                                     };
                            _betDetailRepository.Add(betdetailexact);
                            _betDetailRepository.SaveChanges();
                            return Content("1");
                        }
                    }
            }
            return Content("4");
        }

        #endregion        

        #region Index
        public ActionResult Index()
        {
            return View();
        }
        #endregion        

        #region MatchResult
        public ActionResult MatchResult(int? page)
        {
            var listMatchResult = _matchesRepository
                .GetMany(m => m.IsPlay == 1 & m.Status == false,
                         o => o.OrderByDescending(t => t.EndTime), "HomeTeam,AwayTeam");
            return PartialView("_MatchResult", listMatchResult.AsPagination(page ?? 1, 10));
        }
        #endregion       

        #region MatchInPlay
        public ActionResult MatchInPlay(int? page)
        {
            var listMatchResult = _matchesRepository
                .GetMany(m => m.IsPlay == 2 & m.Status,
                         o => o.OrderByDescending(t => t.EndTime), "HomeTeam,AwayTeam");
            return PartialView("_MatchInPlay", listMatchResult.AsPagination(page ?? 1, 10));
        }
        #endregion

        #region MatchUpComing
        public ActionResult MatchUpComming()
        {
            var listMatch = _matchesRepository.GetMany(m => m.IsPlay == 0 && m.Status, null, "HomeTeam,AwayTeam,League");
            return PartialView("_MatchUpComming", listMatch);
        }
        #endregion   
     
        #region PopupBetSlip
        public ActionResult BetSlip(int id)
        {

            var objBetDetail = _betDetailRepository.GetById(id);
            var objBet = _betRepository.Get(b => b.BetId == objBetDetail.BetId);
            var objMatch = _matchesRepository.GetMany(m => m.MatchId.Equals(objBet.MatchId), null, "HomeTeam,AwayTeam").FirstOrDefault();
            if (ViewBag.Match == null)
            {
                ViewBag.Match = objMatch;
            }
            if (ViewBag.Bet == null)
            {
                ViewBag.Bet = objBet;
            }
            if (ViewBag.objBetDetail == null)
            {
                ViewBag.BetDetail = objBetDetail;
            }
            return PartialView("_popupBetSlip");
        }
        #endregion
    }
}
